package com.sp.scmdb.serviceImpl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sp.scmdb.bean.AddReportBean;
import com.sp.scmdb.bean.EmpMonthReportBean;
import com.sp.scmdb.bean.EmpReportBean;
import com.sp.scmdb.bean.MonitorAreaBean;
import com.sp.scmdb.common.CommonParamter;
import com.sp.scmdb.dao.AreaDao;
import com.sp.scmdb.dao.EmpDayReportDao;
import com.sp.scmdb.dao.EmployeeDao;
import com.sp.scmdb.dao.His_LabelIODao;
import com.sp.scmdb.dao.LabelReadingMachineDao;
import com.sp.scmdb.dao.RealDataDao;
import com.sp.scmdb.dao.ReportUploadDao;
import com.sp.scmdb.dao.ShiftsDetailsDao;
import com.sp.scmdb.entity.Area;
import com.sp.scmdb.entity.EmpDayReport;
import com.sp.scmdb.entity.Employee;
import com.sp.scmdb.entity.His_LabelIO;
import com.sp.scmdb.entity.LabelReadingMachine;
import com.sp.scmdb.entity.RealData;
import com.sp.scmdb.entity.Report_Upload;
import com.sp.scmdb.entity.ShiftsDetails;
import com.sp.scmdb.service.EmpReportService;
import com.sp.scmdb.utils.DateTimeSpan;
import com.sp.scmdb.utils.GroupList;

@Service("empReportService")
public class EmpReportServiceImpl implements EmpReportService {

	private EmpDayReportDao empDayReportDao;
	private ShiftsDetailsDao shiftsDetailsDao;
	private ReportUploadDao ruDao;
	private RealDataDao realDataDao;
	private AreaDao areaDao;
	private LabelReadingMachineDao readerDao; 
	private His_LabelIODao hlDao;
	private EmployeeDao empDao;

	@Autowired
	public void setEmpDao(EmployeeDao empDao) {
		this.empDao = empDao;
	}

	@Autowired
	public void setHlDao(His_LabelIODao hlDao) {
		this.hlDao = hlDao;
	}

	@Autowired
	public void setReaderDao(LabelReadingMachineDao readerDao) {
		this.readerDao = readerDao;
	}

	@Autowired
	public void setViewRealEmpDataDao(RealDataDao realDataDao) {
		this.realDataDao = realDataDao;
	}

	@Autowired
	public void setAreaDao(AreaDao areaDao) {
		this.areaDao = areaDao;
	}

	@Autowired
	public void setRuDao(ReportUploadDao ruDao) {
		this.ruDao = ruDao;
	}

	@Autowired
	public void setShiftsDetailsDao(ShiftsDetailsDao shiftsDetailsDao) {
		this.shiftsDetailsDao = shiftsDetailsDao;
	}

	@Autowired
	public void setEmpDayReportDao(EmpDayReportDao empDayReportDao) {
		this.empDayReportDao = empDayReportDao;
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
	public EmpReportBean getDayReportData(EmpReportBean entity, EmpReportBean oldEntity) {
		List<EmpDayReport> listEmpDayReport = Lists.newArrayList();
		List<EmpReportBean> lists = Lists.newArrayList();
		if (entity.equals(oldEntity)) {
			lists = oldEntity.getAllList();
		} else {
			List<ShiftsDetails> listShiftsDetails = shiftsDetailsDao.queryAll();
			Map<Integer, List<ShiftsDetails>> shiftsDetailMap = GroupList.groupShiftsDetails(listShiftsDetails);
			StringBuilder hql = new StringBuilder("from EmpDayReport where 1=1");
			if (entity.getDepID() != 0) {
				hql.append(" and employee.empDepID='" + entity.getDepID() + "'");
			}
			if (entity.getDutyID() != 0) {
				hql.append(" and employee.empDutyID='" + entity.getDutyID() + "'");
			}
			if (entity.getWorkTypeID() != 0) {
				hql.append(" and employee.empWorkTypeID='" + entity.getWorkTypeID() + "'");
			}
			if (StringUtils.isNotEmpty(entity.getEmpName())) {
				hql.append(" and employee.empName like '%" + entity.getEmpName().trim() + "%'");
			}
			if (StringUtils.isNotEmpty(entity.getLabelID())) {
				hql.append(" and employee.empLableID =" + entity.getLabelID().trim() + "");
			}
			listEmpDayReport = empDayReportDao.queryHql(hql.toString());
			if (CollectionUtils.isNotEmpty(listEmpDayReport)) {
				for (EmpDayReport empDayReport : listEmpDayReport) {
					if (empDayReport.getEmployee() != null) {
						for (Map.Entry<DateTime, DateTime> map : empDayReport.getDataMap().entrySet()) {
							DateTimeSpan dateSpan = new DateTimeSpan(map.getKey(), map.getValue());
							EmpReportBean empReportBean = new EmpReportBean();
							empReportBean.setLabelID(empDayReport.getEmployee().getEmpLableID());
							if(empDayReport.getEmployee().getDepart()!=null){
								empReportBean.setDepName(empDayReport.getEmployee().getDepart().getDeptName());
							}
							empReportBean.setEmpName(empDayReport.getEmployee().getEmpName());
							empReportBean.setEmpID(String.valueOf(empDayReport.getEmpID()));
							if (dateSpan.isTrueDateTime(entity.getInTime()+" 00:00:00", entity.getOutTime())) {
								if (empDayReport.getEmployee().getShifts() != null) {
									String[] shiftDetail=getShift(shiftsDetailMap.get(empDayReport.getEmployee()
											.getShifts().getId()), dateSpan, empDayReport.getEmployee().getShifts()
											.getIsCrossDay()).split(";");
									if(shiftDetail.length>=2){
										empReportBean.setShiftName(shiftDetail[1]);
									}else{
										empReportBean.setShiftName("大班");
									}
									
								}
								Map<DateTime, DateTime> dateTime = Maps.newHashMap();
								dateTime.put(map.getKey(), map.getValue());
								empReportBean.setDataMap(dateTime);
								Integer gong = dateSpan.getMinute(map.getKey(), map.getValue());
								empReportBean.setGong(0);
								if (empDayReport.getEmployee() != null) {
									String minWorkTime = "";
									if (empDayReport.getEmployee().getWorkTime() != null) {
										minWorkTime = empDayReport.getEmployee().getWorkTime().getHourLen();
									}
									String maxWorkTime = "";
									if (empDayReport.getEmployee().getMaxWorkTime() != null) {
										maxWorkTime = empDayReport.getEmployee().getMaxWorkTime().getHourLen();
									}
									if (gong >= Integer.parseInt(minWorkTime == "" ? "0" : minWorkTime)
											&& (gong <= Integer.parseInt(maxWorkTime == "" ? "0" : maxWorkTime) || Integer
													.parseInt(maxWorkTime == "" ? "0" : maxWorkTime) == 0)) {
										empReportBean.setGong(1);
									} else {
										empReportBean.setGong(0);
									}
								}
								empReportBean.setRealTime(String.valueOf(gong));
								lists.add(empReportBean);
							}
						}

					}
				}
			}
		}
		if (CollectionUtils.isNotEmpty(lists)) {
			entity.setAllList(lists);
			entity.setList(lists.subList(entity.getCurrentRow(), entity.getLastRow()));
		}
		return entity;
	}
	
	private String getShift(List<ShiftsDetails> shiftsDetails, DateTimeSpan dateSpan, String isCrossDay) {
		DateTimeFormatter formartter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
		String shiftsName = "0;";
		if (CollectionUtils.isNotEmpty(shiftsDetails)) {
			for (ShiftsDetails shiftsDetail : shiftsDetails) {
				shiftsName = "0;";
				DateTime beginTime = formartter.parseDateTime(dateSpan.getInTime().toString("yyyy-MM-dd") + " "
						+ shiftsDetail.getBeginTime());
				DateTime endTime = formartter.parseDateTime(dateSpan.getInTime().toString("yyyy-MM-dd") + " "
						+ shiftsDetail.getEndTime());
				if (StringUtils.isNotEmpty(isCrossDay) && isCrossDay.equals("1") && endTime.isBefore(beginTime)) {
					if(!beginTime.isBefore(dateSpan.getInTime())){
						beginTime=beginTime.plusDays(-1);
						shiftsName="1;";
					}else{
						endTime=endTime.plusDays(1);
					}
					
				}
				if (!beginTime.isAfter(dateSpan.getInTime()) && !endTime.isBefore(dateSpan.getInTime())) {
					shiftsName += shiftsDetail.getName();
					break;
				}
			}
		}
		return shiftsName;
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
	public EmpReportBean getMonthReportData(EmpReportBean entity, EmpReportBean oldEntity) {
		try {
			List<EmpDayReport> listEmpDayReport = Lists.newArrayList();
			List<EmpMonthReportBean> lists = Lists.newArrayList();
			DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM");
			DateTimeFormatter formatterTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
			DateTime startDate = formatter.parseDateTime(entity.getInTime());
			DateTime endDate = startDate.plusMonths(1);
			if (entity.equals(oldEntity)) {
				lists = oldEntity.getAllList();
			} else {
				List<ShiftsDetails> listShiftsDetails = shiftsDetailsDao.queryAll();
				Map<Integer, List<ShiftsDetails>> shiftsDetailMap = GroupList.groupShiftsDetails(listShiftsDetails);
				StringBuilder hql = new StringBuilder("from EmpDayReport where 1=1");
				if (entity.getDepID() != 0) {
					hql.append(" and employee.empDepID='" + entity.getDepID() + "'");
				}
				if (entity.getDutyID() != 0) {
					hql.append(" and employee.empDutyID='" + entity.getDutyID() + "'");
				}
				if (entity.getWorkTypeID() != 0) {
					hql.append(" and employee.empWorkTypeID='" + entity.getWorkTypeID() + "'");
				}
				if (StringUtils.isNotEmpty(entity.getEmpName().trim())) {
					hql.append(" and employee.empName like '%" + entity.getEmpName().trim() + "%'");
				}
				if (StringUtils.isNotEmpty(entity.getLabelID().trim())) {
					hql.append(" and employee.empLableID ='" + entity.getLabelID().trim() + "'");
				}
				listEmpDayReport = empDayReportDao.queryHql(hql.toString());
				if (CollectionUtils.isNotEmpty(listEmpDayReport)) {
					for (EmpDayReport empDayReport : listEmpDayReport) {
						if (empDayReport.getEmployee() != null&& empDayReport.getEmployee().getShifts()!=null) {
							Map<Integer, String> monthMap = Maps.newHashMap();
							EmpMonthReportBean empMonthBean = new EmpMonthReportBean();
							int totalNum = 0;
							for (Map.Entry<DateTime, DateTime> map : empDayReport.getDataMap().entrySet()) {
								DateTimeSpan dateSpan = new DateTimeSpan(map.getKey(), map.getValue());
								String overDayTime=overDayStr(shiftsDetailMap.get(empDayReport.getEmployee().getShifts()
										.getId()), empDayReport.getEmployee().getShifts()
										.getIsCrossDay());
								if(StringUtils.isNotEmpty(overDayTime)){
									endDate=formatterTime.parseDateTime(endDate.toString("yyyy-MM-dd")+" "+overDayTime);
								}
								if (dateSpan.isTrueDateTimeOfMonth(startDate, endDate)) {
									String shiftName = "";
									String overDayFlag="";
									if (empDayReport.getEmployee().getShifts() != null) {
										shiftName = getShift(shiftsDetailMap.get(empDayReport.getEmployee().getShifts()
												.getId()), dateSpan, empDayReport.getEmployee().getShifts()
												.getIsCrossDay());
									}
									if(shiftName.indexOf(";")>=0){
										String[] shiftDetail=shiftName.split(";");
										overDayFlag=shiftDetail[0];
										if(shiftDetail.length>=2){
											shiftName=shiftDetail[1];
										}else{
											shiftName="";
										}
									}
									if(StringUtils.isEmpty(shiftName)){
										shiftName="大班";
									}
									Integer gong = dateSpan.getMinute(map.getKey(), map.getValue());
									String minWorkTime = "";
									if (empDayReport.getEmployee().getWorkTime() != null) {
										minWorkTime = empDayReport.getEmployee().getWorkTime().getHourLen();
									}
									String maxWorkTime = "";
									if (empDayReport.getEmployee().getMaxWorkTime() != null) {
										maxWorkTime = empDayReport.getEmployee().getMaxWorkTime().getHourLen();
									}
									if (gong >= Integer.parseInt(minWorkTime == "" ? "0" : minWorkTime)
											&& (gong <= Integer.parseInt(maxWorkTime == "" ? "0" : maxWorkTime) || Integer
													.parseInt(maxWorkTime == "" ? "0" : maxWorkTime) == 0)) {
										int dayNum=map.getKey().getDayOfMonth();
										if(overDayFlag.equals("1")){
											if(map.getKey().plusDays(-1).toString("yyyy-MM").equals(startDate.toString("yyyy-MM"))){
												dayNum=map.getKey().plusDays(-1).getDayOfMonth();
											}else{
												dayNum=0;
											}
										}
										if(dayNum!=0){
											if (monthMap.containsKey(dayNum)) {
												if ((monthMap.get(dayNum) == null ? "" : monthMap
														.get(dayNum)).indexOf(shiftName) < 0) {
													
													monthMap.put(dayNum, monthMap.get(dayNum)
															+ "/" + shiftName);
													totalNum++;
												}
											} else {
												monthMap.put(dayNum, shiftName);
												totalNum++;
											}
										}
									}
								}
							}
							if (empDayReport.getEmployee().getDepart() != null) {
								empMonthBean.setDepName(empDayReport.getEmployee().getDepart().getDeptName());
							}
							empMonthBean.setEmpName(empDayReport.getEmployee().getEmpName());
							empMonthBean.setLabelID(String.valueOf(empDayReport.getLabelID()));
							empMonthBean.setMonthMap(monthMap);
							empMonthBean.setTotalWorkNum(totalNum);
							lists.add(empMonthBean);
						}
					}
				}
			}
			if (CollectionUtils.isNotEmpty(lists)) {
				entity.setAllList(lists);
				entity.setList(lists.subList(entity.getCurrentRow(), entity.getLastRow()));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return entity;
	}

	public String overDayStr(List<ShiftsDetails> shiftsDetails, String isCrossDay){
		DateTimeFormatter formartter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
		String shiftsName="";
		for (ShiftsDetails shiftsDetail : shiftsDetails) {
			DateTime beginTime = formartter.parseDateTime(new DateTime().toString("yyyy-MM-dd") + " "
					+ shiftsDetail.getBeginTime());
			DateTime endTime = formartter.parseDateTime(new DateTime().toString("yyyy-MM-dd") + " "
					+ shiftsDetail.getEndTime());
			if (StringUtils.isNotEmpty(isCrossDay) && isCrossDay.equals("1") && endTime.isBefore(beginTime)) {
				shiftsName=shiftsDetail.getEndTime();
			}
		}
		return shiftsName;
	}
	@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
	public List<Report_Upload> findUpload(){
		return ruDao.queryAll();
	}
	@Override
	@Transactional
	public String setUp(String refreshTime){
		Report_Upload ru = new Report_Upload();
		List<Report_Upload> rlList = ruDao.queryAll();
		if(CollectionUtils.isNotEmpty(rlList)){
			ru = rlList.get(0);
			ru.setRefreshTime(refreshTime);
			ru.setIsUsed("1");
			ruDao.update(ru);
		}
		else{
			ru.setRefreshTime(refreshTime);
			ru.setLastID("");
			ru.setLastTime("");
			ru.setState("");
			ru.setIsUsed("1");
			ruDao.save(ru);
		}
		String result = CommonParamter.CHECK_SUCCESS;
		return result;
	}
	@Transactional
	public String initORcancel(Report_Upload ru){
		ruDao.update(ru);
		String result = CommonParamter.CHECK_SUCCESS;
		return result;
	}

	@Transactional(readOnly = true,isolation=Isolation.READ_UNCOMMITTED)	
	public List<EmpReportBean> uploadReport() {
		List<EmpDayReport> listEmpDayReport = Lists.newArrayList();
		List<EmpReportBean> lists = Lists.newArrayList();
		List<ShiftsDetails> listShiftsDetails = shiftsDetailsDao.queryAll();
		Map<Integer, List<ShiftsDetails>> shiftsDetailMap = GroupList.groupShiftsDetails(listShiftsDetails);
		Map<String,String> m = new HashMap<String, String>();
		StringBuilder hql = new StringBuilder("from EmpDayReport where 1=1 and employee.duty.dutyLevelId<4");
		listEmpDayReport = empDayReportDao.queryHql(hql.toString());
		if (CollectionUtils.isNotEmpty(listEmpDayReport)) {
			for (EmpDayReport empDayReport : listEmpDayReport) {
				if (empDayReport.getEmployee() != null) {
					for (Map.Entry<DateTime, DateTime> map : empDayReport.getDataMap().entrySet()) {
						DateTimeSpan dateSpan = new DateTimeSpan(map.getKey(), map.getValue());
						EmpReportBean empReportBean = new EmpReportBean();
						empReportBean.setEmpID(String.valueOf(empDayReport.getEmpID()));
						if (empDayReport.getEmployee().getShifts() != null) {
							m = getShifts(shiftsDetailMap.get(empDayReport.getEmployee()
									.getShifts().getId()), dateSpan, empDayReport.getEmployee().getShifts()
									.getIsCrossDay());
							for (Map.Entry<String, String> ms : m.entrySet()) {
								empReportBean.setShiftID(ms.getKey());
								empReportBean.setShiftName(ms.getValue());
							}
						}
						empReportBean.setInTime(map.getKey().toString("yyyy-MM-dd HH:mm:ss"));
						empReportBean.setOutTime(map.getValue().toString("yyyy-MM-dd HH:mm:ss"));
						lists.add(empReportBean);
					}
				}
			}
		}
		return lists;
	}

	private Map<String,String> getShifts(List<ShiftsDetails> shiftsDetails, DateTimeSpan dateSpan, String isCrossDay) {
		Map<String,String> map = new HashMap<String, String>();
		DateTimeFormatter formartter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
		String shiftsID = "";
		String shiftsName = "";
		if (CollectionUtils.isNotEmpty(shiftsDetails)) {
			for (ShiftsDetails shiftsDetail : shiftsDetails) {
				DateTime beginTime = formartter.parseDateTime(dateSpan.getInTime().toString("yyyy-MM-dd") + " "
						+ shiftsDetail.getBeginTime());
				DateTime endTime = formartter.parseDateTime(dateSpan.getInTime().toString("yyyy-MM-dd") + " "
						+ shiftsDetail.getEndTime());
				if (StringUtils.isNotEmpty(isCrossDay) && isCrossDay.equals("1") && endTime.isBefore(beginTime)) {
					if(!beginTime.isBefore(dateSpan.getInTime())){
						beginTime=beginTime.plusDays(-1);
					}else{
						endTime=endTime.plusDays(1);
					}
				}
				if (!beginTime.isAfter(dateSpan.getInTime()) && !endTime.isBefore(dateSpan.getInTime())) {
					shiftsID = shiftsDetail.getId()+"";
					shiftsName = shiftsDetail.getName();
					break;
				}
			}
		}
		map.put(shiftsID, shiftsName);
		return map;
	}
	
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true,isolation=Isolation.READ_UNCOMMITTED)
	public Map<String,List> numberPeople(){
		Map<String,List> map = new HashMap<String, List>();
		//获取园内人数
		String entryCount = "";
		String Hql = "from ViewRealEmpData ";
		List<RealData> entryList = realDataDao.queryHql(Hql);
		if(CollectionUtils.isNotEmpty(entryList)){
			entryCount = entryList.size()+"";
		}
		//获取各区域人数
		String empCount = "";
		List<Area> listArea = areaDao.queryAll();
		List<MonitorAreaBean> listAreaBean = new ArrayList<MonitorAreaBean>();
		if(CollectionUtils.isNotEmpty(listArea)){
			for(int i=0;i<listArea.size();i++){
				MonitorAreaBean areaBean = new MonitorAreaBean();
				areaBean.setId(listArea.get(i).getId()+"");
				areaBean.setName(listArea.get(i).getName());
				areaBean.setReaders(listArea.get(i).getReaders());
				if(!areaBean.getReaders().isEmpty()){
					Hql = "SELECT count(empID) as empCount FROM VIEW_REAL_DATA VRD where VRD.lrmID IN (" + areaBean.getReaders() + ")";
					empCount = ((Map) realDataDao.findBySql(Hql.toString()).get(0)).get("empCount").toString();
					if (!empCount.isEmpty()) {
						areaBean.setRelEmpCount(Integer.parseInt(empCount));
					}
				} else {
					areaBean.setRelEmpCount(0);
				}
				listAreaBean.add(areaBean);
			}
		}
		map.put(entryCount, listAreaBean);
		return map;
	}

	@Transactional(readOnly = true,isolation=Isolation.READ_UNCOMMITTED)
	public List<LabelReadingMachine> readerList(){
		return readerDao.queryAll();
	}
	
	@Transactional
	public String addReport(AddReportBean adBean){
		int empID = 0;
		List<Employee> empList = empDao.queryHql("from Employee where empLabelID='"+adBean.getLabelID()+"'");
		if(CollectionUtils.isNotEmpty(empList)){
			Employee emp = empList.get(0);
			empID = emp.getId();
			DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
			if(StringUtils.isNotEmpty(adBean.getReader()) && StringUtils.isNotEmpty(adBean.getStartTime()) && StringUtils.isNotEmpty(adBean.getEndTime())){
				String[] reader = adBean.getReader().split(",");
				String[] startTime = adBean.getStartTime().split(",");
				String[] endTime = adBean.getEndTime().split(",");
				for(int i=0;i<reader.length;i++){
					His_LabelIO hislabel = new His_LabelIO();
					hislabel.setLabelID(Integer.parseInt(adBean.getLabelID()));
					hislabel.setEmpID(empID);
					hislabel.setLrmID(Integer.parseInt(reader[i].trim()));
					hislabel.setInTime(format.parseDateTime(startTime[i].trim()));
					hislabel.setOutTime(format.parseDateTime(endTime[i].trim()));
					hlDao.save(hislabel);
				}
			}
			EmpDayReport updateReport = new EmpDayReport();
			updateReport.setEmpID(empID);
			updateReport.setLabelID(Integer.parseInt(adBean.getLabelID()));
			Map<DateTime, DateTime> map = new HashMap<DateTime, DateTime>();
			List<EmpDayReport> reportList = empDayReportDao
					.queryHql("from EmpDayReport where empID=" + empID);
			if (CollectionUtils.isNotEmpty(reportList)) {
				EmpDayReport Report = reportList.get(0);
				map = Report.getDataMap();
				if (map.containsKey(format.parseDateTime(adBean.getInEntryTime()))) {
					map.remove(adBean.getInEntryTime());
				}
				map.put(format.parseDateTime(adBean.getInEntryTime()), format.parseDateTime(adBean.getOutEntryTime()));
				Report.setDataMap(map);
				empDayReportDao.update(Report);
			}else{
				map.put(format.parseDateTime(adBean.getInEntryTime()), format.parseDateTime(adBean.getOutEntryTime()));
				empDayReportDao.save(updateReport);
			}
		}
		return "success";
	}
	
}
